【CDK】EC2が停止したらEventBridgeを使用してSNSでEメール通知を受け取る方法

【CDK】EC2が停止したらEventBridgeを使用してSNSでEメール通知を受け取る方法

Clock Icon2024.07.13

リテールアプリ共創部のるおんです。
今回は、EC2インスタンスが停止したときにEventBridgeを使用して、SNSを通じてEメールで通知を受け取る機能をCDKで実装してみました!
使用言語はTypeScriptです。

Amazon EventBridgeとは

EventBridgeは、AWSのサービス間やアプリケーションのイベントを連携させるためのサーバーレスイベントバスサービスです。様々なAWSサービスからのイベントを監視し、指定したルールに基づいて特定のアクションを実行することができます。

参考:Amazon EventBridge とは

全体像

今回は以下の構成をAWS CDKを用いてデプロイします。

EC2インスタンスの停止をEventBridgeで監視し、停止イベントを検知したらSNSを通じてEメールを送信するというシンプルな構成です。

スクリーンショット 2024-07-13 5.20.31

CDK書いてみる

それではこの構成をCDKで実装していきます。
TypeScriptが使用可能で、AWS CDKを用いて手元のマシンからデプロイができる環境が整っていることを前提に進めていきます。

実装

まず、プロジェクトを作成してCDKを開始します。

mkdir ec2_stop_notification
cd ec2_stop_notification
cdk init app --language typescript

CDKプロジェクトが構築できたら、lib/ec2_stop_notification-stack.tsに以下のコードを記述します。

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sns from 'aws-cdk-lib/aws-sns';
import * as subscriptions from 'aws-cdk-lib/aws-sns-subscriptions';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';

export class Ec2StopNotificationStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // SNSトピックの作成
    const topic = new sns.Topic(this, 'EC2StopTopic', {
      topicName: 'ec2-stop-notification',
      displayName: 'EC2インスタンスが停止しました。',
    });

    // SNSトピックにEメールサブスクリプションを追加
    topic.addSubscription(new subscriptions.EmailSubscription('[email protected]'));

    // EventBridgeルールを作成
    const rule = new events.Rule(this, 'EC2StopRule', {
      eventPattern: {
        source: ['aws.ec2'],
        detailType: ['EC2 Instance State-change Notification'],
        detail: {
          state: ['stopped'],
          "instance-id": ['i-xxxxxxxxxxxxxxxxx'],
        },
      },
    });

    // ルールのターゲットとしてSNSトピックを追加
    rule.addTarget(new targets.SnsTopic(topic));
  }
}

解説

それでは、このコードについて簡単に解説します。

 // SNSトピックの作成
    const topic = new sns.Topic(this, 'EC2StopTopic', {
      topicName: 'ec2-stop-notification',
      displayName: 'EC2インスタンスが停止しました。',
    });

    // SNSトピックにEメールサブスクリプションを追加
    topic.addSubscription(new subscriptions.EmailSubscription('[email protected]'));

ここでは、SNSトピックを作成し、指定したメールアドレスをサブスクライバーとして追加しています。
このトピックは、EC2インスタンスが停止した際に通知を送るために使用されます。
displayNameを指定することで、メールの件名を任意の文字列に指定することができます。

    // EventBridgeルールを作成
    const rule = new events.Rule(this, 'EC2StopRule', {
      eventPattern: {
        source: ['aws.ec2'],
        detailType: ['EC2 Instance State-change Notification'],
        detail: {
          state: ['stopped'],
          "instance-id": ['i-xxxxxxxxxxxxxxxxx'],
        },
      },
    });

    // ルールのターゲットとしてSNSトピックを追加
    rule.addTarget(new targets.SnsTopic(topic));

ここでは、EventBridgeルールを作成しています。そして、作成したEventBridgeルールのターゲットとして、先ほど作成したSNSトピックを設定しています。
このルールは、特定のEC2インスタンスの状態が stopped に変更されたときにトリガーされます。eventPatternでイベントのソース、タイプ、詳細を指定しています。
検知したいインスタンスのIDを指定してください。

これにより、ルールがトリガーされたときにSNSトピックに通知が送られます。

デプロイ

スタックをデプロイします。

cdk deploy

デプロイが完了したら、正しくリソースが作成されていることを確認します。

また、指定したメールアドレスにSNSのサブスクリプション確認メールが届くので、「Confirm subscription」と書かれたリンクをクリックしてサブスクリプションを承認してください。

動作確認

それでは動作確認をしてみましょう。実際にEC2インスタンスを停止させて、Eメールが届くか確認します。

AWSマネジメントコンソールにログインし、EC2ダッシュボードに移動します。
任意のEC2インスタンスを選択し、「インスタンスの状態」から「インスタンスを停止」を選択します。
少し待つと、指定したメールアドレスに通知が届くはずです。

スクリーンショット 2024-07-13 4.50.36
無事メールが届いていることが確認できました。

最後に

今回は、EventBridge+SNSの構成をAWS CDKでデプロイし、EC2インスタンスの停止を監視する方法を紹介しました。

この方法を応用すれば、EC2インスタンスの起動や再起動など、他の状態変化も監視できます。また、EC2以外のAWSリソースの状態変化も同様の方法で監視可能です。

ただし、ブログを書いている際に気づいたのですが、AWS User Notificationsを使用すれば、もっと簡単にEC2インスタンスの状態をEメール送信することができるようです。

https://dev.classmethod.jp/articles/ec2-nstance-state-change-aws-user-notifications/

参考になりましたら幸いです!

参考

Amazon EventBridge とは
AWS CDK API Reference
AWS::Events::Rule - AWS CloudFormation
AWS User Notifications

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.